#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "packet_queue.h"
#include "userLog.h"

Packet *PacketMalloc(uint32_t len)
{
    int ret;
    Packet *p = (Packet *)malloc(sizeof(Packet));
    memset(p, 0, sizeof(Packet));
    POINTER_CHECK(p);
    p->next = NULL;
    p->prev = NULL;
    uint32_t pkt_len = len;
    p->pkt_data = (uint8_t *)malloc(pkt_len);
    memset(p->pkt_data, 0, pkt_len);
    POINTER_CHECK(p->pkt_data);
    return p;
}

void copy_packet(Packet *p, int len, uint8_t *data)
{
    memcpy(p->pkt_data, data, len);
    p->pkt_len = len;
}

void pkt_free(Packet *p)
{
    if (p)
    {
        if (p->pkt_data != NULL)
        {
            free(p->pkt_data);
            p->pkt_data = NULL;
        }
        free(p);
        p = NULL;
    }
    return;
}

void PacketEnqueue(PacketQueue *q, Packet *p)
{
    if (p == NULL)
        return;

    /* more packets in queue */
    if (q->top != NULL)
    {
        p->prev = NULL;
        p->next = q->top;
        q->top->prev = p;
        q->top = p;
        /* only packet */
    }
    else
    {
        p->prev = NULL;
        p->next = NULL;
        q->top = p;
        q->bot = p;
    }
    q->len++;
}

Packet *PacketDequeue(PacketQueue *q)
{
    Packet *p = NULL;

    /* if the queue is empty there are no packets left. */
    if (q->len == 0)
    {
        return NULL;
    }

    q->len--;

    /* pull the bottom packet from the queue */
    p = q->bot;

    /* Weird issue: sometimes it looks that two thread arrive
     * here at the same time so the bot ptr is NULL (only on OS X?)
     */
    if (p == NULL)
        return NULL;

    /* more packets in queue */
    if (q->bot->prev != NULL)
    {
        q->bot = q->bot->prev;
        q->bot->next = NULL;
        /* just the one we remove, so now empty */
    }
    else
    {
        q->top = NULL;
        q->bot = NULL;
    }

    p->next = NULL;
    p->prev = NULL;
    return p;
}

bool PacketIsEmpty(PacketQueue *pq)
{
    if (pq->bot || pq->top)
        return false;
    return true;
}
